package com.songtai.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.songtai.dao.GenericDao;
import com.songtai.util.PageBean;

public class GenericDaoImplHibernate<T> extends HibernateDaoSupport implements
		GenericDao<T> {


	protected Class<T> entityClass;

	/**
	 * 构造方法
	 */
	@SuppressWarnings("unchecked")
	protected GenericDaoImplHibernate() {
		entityClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	protected Class<T> getEntityClass() {
		return entityClass;
	}

	/**
	 * 根据ID查询实体
	 */
	@SuppressWarnings("unchecked")
	public T readObjectById(Serializable id) {
		return (T) this.getHibernateTemplate().load(this.entityClass, id);
	}

	/**
	 * 保存单个实体
	 */
	@SuppressWarnings("unchecked")
	public Serializable createObject(T entity) {
		return (Serializable) this.getHibernateTemplate().save(entity);
	}

	/**
	 * 根据条件删除多个实体
	 */
	public void deleteEntities(String hql) {
		final String hqlTemp = hql;
		this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hqlTemp);
				query.executeUpdate();
				return null;
			}
		});
	}

	/**
	 * 删除一个实体
	 */
	public void deleteObject(T entity) {
		this.getHibernateTemplate().delete(entity);
	}

	/**
	 * 查询所有实体
	 */
	@SuppressWarnings("unchecked")
	public List<T> readAll(String className) {
		return this.getHibernateTemplate().find("from " + className);
	}

	/**
	 * 根据条件查询实体集合
	 */
	@SuppressWarnings("unchecked")
	public List<T> readByCondition(String hql, Object[] objs) {
		return this.getHibernateTemplate().find(hql, objs);
	}

	/**
	 * 保存多个实体
	 */
	public void createEntities(Collection<T> entities) {
		for (Iterator<T> iterator = entities.iterator(); iterator.hasNext();) {
			T entity = (T) iterator.next();
			this.getHibernateTemplate().save(entity);
		}
	}

	/**
	 * 更新实体
	 */
	public void updateObject(T entity) {
		this.getHibernateTemplate().update(entity);
	}

	/**
	 * 分页查询
	 */
	public PageBean findPageEntities(final PageBean pageBean) {

		// 查询记录集
		this.getHibernateTemplate().execute(new HibernateCallback() {
			@SuppressWarnings("unchecked")
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = null;
				query = session.createQuery(pageBean.getCountHql());
				int counts = ((Long) query.uniqueResult()).intValue();
				// 设置总记录数
				pageBean.setAllCounts(counts);
				if (counts > 0) {
					int pages = (counts - 1) / pageBean.getEndIndex() + 1;
					// 设置总页数
					pageBean.setAllPages(pages);
					query = session.createQuery(pageBean.getEntiesHql())
							.setFirstResult(pageBean.getStartIndex())
							.setMaxResults(pageBean.getEndIndex());
					List list = query.list();
					// 设置集合
					pageBean.setObjs(list);
				}
				return null;
			}
		});
		return pageBean;
	}

	/**
	 * 分页查询集合BySQL
	 */
	@Override
	public PageBean findPageEntitiesBySql(final PageBean pageBean) {

		// 查询记录集
		Session session = this.getSession();

		Query query = null;
		query = session.createSQLQuery(pageBean.getCountHql());
		String temp = query.uniqueResult().toString();
		int counts = Integer.parseInt(temp);
		// 设置总记录数
		pageBean.setAllCounts(counts);
		if (counts > 0) {
			int pages = (counts - 1) / pageBean.getEndIndex() + 1;
			// 设置总页数
			pageBean.setAllPages(pages);
			query = session.createQuery(pageBean.getEntiesHql());
			List list = query.list();
			// 设置集合
			pageBean.setObjs(list);
		}
		return pageBean;
	}

	/**
	 * 添加或者保存
	 */
	public void saveOrUpdateEntity(T entity) {
		this.getHibernateTemplate().saveOrUpdate(entity);
	}


}
